/*
 * ZENworks Notification Icon
 * Copyright (C) Author: Gangadhar Nagesh Metla (Novell, Inc.)
 * nmetla74@gmail.com 
 * Version 1.0
 * 1/3/2009
 * Filename ZProgressPanel.java
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package com.novell.zenworks.agent.zicon.progress;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.rmi.RemoteException;
import java.util.Locale;
import java.util.Timer;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

import com.novell.zenworks.agent.common.Paths;
import com.novell.zenworks.agent.common.ICommonUIEnums.MB_ICON;
import com.novell.zenworks.agent.common.ICommonUIEnums.MB_RESPONSE;
import com.novell.zenworks.agent.common.ICommonUIEnums.MB_TYPE;
import com.novell.zenworks.agent.zbrowser.MessageBoxLauncher;
import com.novell.zenworks.agent.zicon.ZTrayIcon;
import com.novell.zenworks.zicon.common.LogUtil;
import com.novell.zenworks.zicon.common.progress.ITaskSetProgress;
import com.novell.zenworks.zicon.common.progress.ITaskSetProgress.ProgressStatus;
public class ZProgressPanel extends JPanel
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public JLabel iconLabel;
    public JLabel statusMessageLabel;
    public JLabel titleLabel;
    public JLabel messageLabel;
    public JHyperLabel removeLink;
    public JHyperLabel postponeLink;
    public JProgressBar progressBar;
    public JLabel finishLabel;
    public ITaskSetProgress progress;
    private final Font font = new Font("Trebuchet MS", Font.PLAIN, 11);
    private final Font bfont = new Font("Trebuchet MS", Font.BOLD, 11);
    private final Color white = Color.WHITE;
    private final Color yellow = Color.YELLOW;
    private final Color black = Color.BLACK;
    private boolean selected = false;
    public ZProgressPanel (ITaskSetProgress progress) throws Exception 
    {      
      this.progress = progress;      
      progressBar = new javax.swing.JProgressBar();
      finishLabel = new javax.swing.JLabel();
      iconLabel = new javax.swing.JLabel();
      statusMessageLabel = new javax.swing.JLabel();
      titleLabel = new javax.swing.JLabel();
      messageLabel = new javax.swing.JLabel();
      removeLink = new JHyperLabel();
      postponeLink = new JHyperLabel();

      setName(progress.getUID());
      setFont(font);
      setLayout(new java.awt.GridBagLayout());
      setBackground(white);

      initProgressBar();
      initFinishLabel();
      initIconLabel();
      initstatusMessageLabel();
      initTitleLabel();
      initMessageLabel();
      initRemoveLink();
      initPostponeLink();
      setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, black));
      addMouseListener();
      initializeComponentUsage();
  }
    
    private void initializeComponentUsage() throws Exception
    {
        if (progress.getStatus() != null && progress.getStatus().equals(ProgressStatus.Downloading))
        {
            progressBar.setIndeterminate(false);
            if (progress.getTotalTasks() > 1)
            {
                statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithTaskAndPercent", new String[]{ progressStatusToString(progress.getStatus()), 
                        String.valueOf(progress.getCurrentTask()), String.valueOf(progress.getTotalTasks()), String.valueOf(Math.min(progress.getPercent(), 100))}));
            }
            else
            {
                statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithPercent", new String[]{
                        progressStatusToString(progress.getStatus()), String.valueOf(Math.min(progress.getPercent(), 100))}));
            }
        }
        else
        {
            progressBar.setIndeterminate(true);
            if (progress.getTotalTasks() > 1)
            {
                statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithTask", new String[]{
                        progressStatusToString(progress.getStatus()), String.valueOf(progress.getCurrentTask()), String.valueOf(progress.getTotalTasks())}));
            }
            else
            {
                statusMessageLabel.setText(progressStatusToString(progress.getStatus()));
            }
        }
        
        if(progress.getTranslatedMessage(Locale.getDefault()) != null )
            messageLabel.setText(progress.getTranslatedMessage(Locale.getDefault()));

        progressBar.setValue((progress.getPercent() <= progressBar.getMaximum()) ? (progress.getPercent() * progressBar.getMaximum()/100) : progressBar.getMaximum());
        //progress.UpdateTicker += new ProgressUpdateTicker(OnProgressUpdated);

        if (progress.canPostpone())
        {
            postponeLink.setVisible(true);
        }
        else
        {
            postponeLink.setVisible(false);
        }        
    }

    private void addMouseListener()
    {
        this.addMouseListener(new MouseListener(){

            public void mouseClicked(MouseEvent event)
            {
                if(!selected)
                {
                    try
                    {
                        ZProgressDialog.getInstance().unSelectAll();
                        selected = true;
                        event.getComponent().setBackground(yellow);
                        removeLink.setSelected(true);
                    } catch (Exception e)
                    {
                        try
                        {
                            LogUtil.LogException(e.getMessage(), e);
                            if(e.getLocalizedMessage() != null)
                            {
                                MessageBoxLauncher.ShowMessageBoxHandler(e.getLocalizedMessage(), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                            }
                            else
                            {
                                MessageBoxLauncher.ShowMessageBoxHandler(ZTrayIcon.rm.getString("RemotingError"), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                            }
                        } catch (Exception e1)
                        {
                            LogUtil.LogException(e.getMessage(), e1);
                        }
                    }
                }
                else
                {
                    selected = false;
                    event.getComponent().setBackground(white);
                    removeLink.setSelected(false);
                }
                validate();
            }

            public void mouseEntered(MouseEvent e)
            {
            }

            public void mouseExited(MouseEvent e)
            {
            }

            public void mousePressed(MouseEvent e)
            {
            }

            public void mouseReleased(MouseEvent e)
            {
            }});
    }
    private void initPostponeLink() throws Exception
    {
        GridBagConstraints gridBagConstraints;
        postponeLink.setText(ZTrayIcon.rm.getString("PostponeLinkLabel"));
        postponeLink.setName("postponeLink");
        postponeLink.setUrl(progress.getUID());
        postponeLink.setFont(font);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        add(postponeLink, gridBagConstraints);        
    }
    
    private void initRemoveLink() throws Exception
    {
        removeLink.setText(ZTrayIcon.rm.getString("RemoveLinkLabel"));
        removeLink.setName("removeLink");
        removeLink.setUrl(progress.getUID());
        removeLink.setFont(font);
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
        add(removeLink, gridBagConstraints);        
    }
    private void initMessageLabel()
    {
        messageLabel.setText("");
        messageLabel.setName("messageLabel");
        messageLabel.setFont(font);
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
        add(messageLabel, gridBagConstraints);        
    }
    private void initTitleLabel() throws Exception
    {
        GridBagConstraints gridBagConstraints;
        titleLabel.setText(progress.getName());
        titleLabel.setName("titleLabel");
        titleLabel.setFont(bfont);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = 141;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 0);
        add(titleLabel, gridBagConstraints);        
    }
    private void initstatusMessageLabel() throws Exception
    {
        statusMessageLabel.setFont(font);
        statusMessageLabel.setText("");
        statusMessageLabel.setName("statusMessageLabel");
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 52;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
        add(statusMessageLabel, gridBagConstraints);        
    }
    private void initIconLabel() throws Exception
    {
        iconLabel.setText("");        
        iconLabel.setName("iconLabel");
        iconLabel.setFont(font);
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.gridwidth = 1;
        gridBagConstraints.ipady = 14;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        add(iconLabel, gridBagConstraints);
        
    }
    private void initFinishLabel()
    {
        finishLabel.setText(ZTrayIcon.rm.getString("ProgressStatusAborted"));
        finishLabel.setName("finishLabel");
        finishLabel.setFont(font);
        
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 147;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 5, 0);
        gridBagConstraints.weightx = 1.0;
        add(finishLabel, gridBagConstraints);
        
    }
    
    private void initProgressBar()
    {
        progressBar.setBackground(Color.WHITE);
        progressBar.setForeground(Color.BLACK);
        progressBar.setMaximum(200);
        progressBar.setAutoscrolls(true);
        progressBar.setIndeterminate(true);
        progressBar.setMaximumSize(new java.awt.Dimension(32767, 12));
        progressBar.setMinimumSize(new java.awt.Dimension(50, 12));
        progressBar.setName("progressBar");
        progressBar.setPreferredSize(new java.awt.Dimension(100, 12));
        progressBar.setRequestFocusEnabled(true);
        
        progressBar.addMouseListener(new MouseListener(){

            public void mouseClicked(MouseEvent event)
            {
                if(event.getComponent().getParent() == null)
                    return;
                
                if(!selected)
                {
                    try
                    {
                        ZProgressDialog.getInstance().unSelectAll();
                        selected = true;
                        event.getComponent().getParent().setBackground(yellow);
                        removeLink.setSelected(true);
                    } catch (Exception e)
                    {
                        try
                        {
                            LogUtil.LogException(e.getMessage(), e);
                            if(e.getLocalizedMessage() != null)
                            {
                                MessageBoxLauncher.ShowMessageBoxHandler(e.getLocalizedMessage(), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                            }
                            else
                            {
                                MessageBoxLauncher.ShowMessageBoxHandler(ZTrayIcon.rm.getString("RemotingError"), ZTrayIcon.rm.getString("PropDlgTitle") , MB_TYPE.MBT_OK, MB_ICON.MBI_ERROR, 30, false, MB_RESPONSE.MBR_OK);
                            }
                        } catch (Exception e1)
                        {
                            LogUtil.LogException(e.getMessage(), e1);
                        }
                    }
                }
                else
                {
                    selected = false;
                    event.getComponent().getParent().setBackground(white);
                    removeLink.setSelected(false);
                }
                validate();                                
            }

            public void mouseEntered(MouseEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void mouseExited(MouseEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void mousePressed(MouseEvent e)
            {
                // TODO Auto-generated method stub
                
            }

            public void mouseReleased(MouseEvent e)
            {
                // TODO Auto-generated method stub
                
            }});
        
        GridBagConstraints gridBagConstraints;
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.ipadx = 147;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 5, 0);
        gridBagConstraints.weightx = 1.0;
        add(progressBar, gridBagConstraints);
        
    }
    
    public void update(ITaskSetProgress progress) throws Exception
    {
        this.progress = progress; 
       /* if(progress.isComplete())
        {
            progressBar.setVisible(false);
            //finishLabel.setText("Completed"); //I18N

            Timer t = new Timer();
            t.schedule(new ZProgressRemovalTimer(progress.getUID()), 30000);
        }*/
        
       
        
        /*statusMessageLabel.setText(progress.getTranslatedMessage());
        titleLabel.setText(progress.getName());
        messageLabel.setText(progress.getTranslatedMessage());
        
        if(progress.canPostpone())
            postponeLink = new JHyperLabel();*/ 
        
        /*if (InvokeRequired)
        {
            Invoke(new ProgressUpdateTicker(OnProgressUpdated), progress);
            return;
        }*/
        
        iconLabel.setText("");
        setImageIcon();

        boolean isComplete = false;
        if (progress instanceof ITaskSetProgress)
        {
            ITaskSetProgress taskProgress =  (ITaskSetProgress) progress;

            int currentTask = taskProgress.getCurrentTask();
            int totalTasks = taskProgress.getTotalTasks();

            titleLabel.setText(taskProgress.getName());
            isComplete = taskProgress.isComplete();

            if (taskProgress.getStatus() != null && 
               (taskProgress.getStatus().equals(ProgressStatus.Installing) ||
                taskProgress.getStatus().equals(ProgressStatus.Launching) ||
                taskProgress.getStatus().equals(ProgressStatus.ScanningInventory) ||
                taskProgress.getStatus().equals(ProgressStatus.Terminating) ||
                taskProgress.getStatus().equals(ProgressStatus.Uninstalling) ||
                taskProgress.getStatus().equals(ProgressStatus.Verifying)))
            {
                progressBar.setIndeterminate(true);
                if (totalTasks > 1)
                {
                    statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithTask", new String[]{
                        progressStatusToString(taskProgress.getStatus()), String.valueOf(currentTask), String.valueOf(totalTasks)}));
                }
                else
                {
                    statusMessageLabel.setText(progressStatusToString(taskProgress.getStatus()));
                }
            }
            else if (taskProgress.getStatus() != null && taskProgress.getStatus().equals(ProgressStatus.Downloading))
            {
                progressBar.setIndeterminate(false);
                progressBar.setValue((progress.getPercent() <= progressBar.getMaximum()) ? (progress.getPercent() * progressBar.getMaximum()/100) : progressBar.getMaximum());
                if (totalTasks > 1)
                {
                    statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithTaskAndPercent", new String[]{
                        progressStatusToString(taskProgress.getStatus()), String.valueOf(currentTask), String.valueOf(totalTasks), String.valueOf(Math.min(taskProgress.getPercent(), 100))}));
                }
                else
                {
                    statusMessageLabel.setText(ZTrayIcon.rm.getString("StatusLabelTextFormatWithPercent", new String[] {
                        progressStatusToString(taskProgress.getStatus()), String.valueOf(Math.min(taskProgress.getPercent(), 100))}));
                }
            }
                
            messageLabel.setText(progress.getTranslatedMessage(Locale.getDefault()));
        }
        else
        {
            messageLabel.setText(progress.getTranslatedMessage(Locale.getDefault()));
            progressBar.setValue((progress.getPercent() <= progressBar.getMaximum()) ? (progress.getPercent() * progressBar.getMaximum()/100) : progressBar.getMaximum());
            if (progress.getPercent() == 100)
            {
                isComplete = true;
            }
        }
        
        postponeLink.setVisible(progress.canPostpone());
        if (isComplete)
        {
            //progress.UpdateTicker -= OnProgressUpdated;
            postponeLink.setVisible(false);
            finishLabel.setText(ZTrayIcon.rm.getString("StatusComplete"));
            finishLabel.setVisible(true);
            progressBar.setVisible(false);
            if (progress instanceof ITaskSetProgress)
            {
                ITaskSetProgress taskProgress = (ITaskSetProgress)progress;
                statusMessageLabel.setText(progressStatusToString(taskProgress.getStatus()));
            }

            // The operation is complete, start a thread to remove the progress from the status window.
/*            Thread thread = new Thread(new ThreadStart (RemoveStatusThread));
            thread.Start();*/
            Timer t = new Timer();
            t.schedule(new ZProgressRemovalTimer(progress.getUID()), 30000);
        }
        else if (progress.isAborted())
        {
            //progress.UpdateTicker -= OnProgressUpdated;
            postponeLink.setVisible(false);
            finishLabel.setText(ZTrayIcon.rm.getString("StatusAborted"));
            finishLabel.setVisible(true);
            progressBar.setVisible(false);
            if (progress instanceof ITaskSetProgress)
            {
                ITaskSetProgress taskProgress = (ITaskSetProgress)progress;
                statusMessageLabel.setText(progressStatusToString(taskProgress.getStatus()));
            }
        }

    }
    
    private String progressStatusToString(ProgressStatus status) throws Exception
    {
        String localizedString = null;
        if(progress.getStatus() == null)
        {
            return ZTrayIcon.rm.getString("ProgressStatusDownloading");
        }
        
        switch (progress.getStatus())
        {
            case Downloading :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusDownloading");
                break;
            }
            case Installing :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusInstalling");
                break;
            }
            case Uninstalling :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusUninstalling");
                break;
            }
            case ScanningInventory :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusScanningInventory");
                break;
            }
            case Launching :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusLaunching");
                break;
            }
            case Verifying :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusVerifying");
                break;
            }
            case Terminating :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusTerminating");
                break;
            }
            case Finished :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusFinished");
                break;
            }
            case Aborted :
            {
                localizedString = ZTrayIcon.rm.getString("ProgressStatusAborted");
                break;
            }
            default:
                localizedString = progress.getStatus().toString();
        }
        return localizedString;
    }
    
    public boolean isSelected()
    {
        return this.selected;
    }

    public void setSelected(boolean choice)
    {
        selected = choice;
        removeLink.setSelected(choice);
        if(choice)
        {
            setBackground(yellow);
        }
        else
        {
            setBackground(white);
        }
    }
    
    public void setImageIcon() throws RemoteException
    {
    	if(progress.getIconPath() != null)
        {
            ImageIcon icon = new ImageIcon(progress.getIconPath());
            icon.setImageObserver(iconLabel);
            iconLabel.setIcon(icon);
        }
    	iconLabel.revalidate();
    	this.validate();
    }
}


